// Driver Init module
#include "burner.h"
#include "tracklst.h"
#include "eeprom.h"

int driverOkay = 0;					// 1 if the Driver has been initted okay, and it's okay to use the BurnDrv functions

static bool bSaveRAM = false;

static int DoLibInit()				// Do Init of Burn library driver
{
	int ret = 0;

	romLoader.open();

	// If there is a problem with the romset, report it
	if (romLoader.status() != RomLoader::RL_STATUS_OK) {
#ifndef FBA_DEBUG
		// Don't even bother trying to start the game if we know it won't work
		romLoader.close();
		return 1;
#endif
	}

	progressCreate();

	ret = BurnDrvInit();

	romLoader.close();

	progressDestroy();

	if (ret) {
		return 3;
	} else {
		return 0;
	}
}

// no need to reinit media when init a driver, modified by regret
int BurnerDrvInit(int drvNum, bool restore)
{
	BurnerDrvExit();				// Make sure exitted

	BurnSetDrvSelect(drvNum);		// Set the driver number

	// Define maxPlayers early; gameInpInit() needs it (normally defined in DoLibInit()).
	maxPlayers = BurnDrvGetMaxPlayers();

	gameInpInit();					// Init game input
	if (configGameLoad(true)) {
		loadDefaultInput();			// load default input mapping
	}
	inputInterface.make(true);
	gameInpDefault();

	if (kNetGame) {
		nBurnCPUSpeedAdjust = 0x0100;
	}

#ifndef NO_IPS
	patcher.enabled = true; // play with ips
	loadActivePatches();
#endif

	int status = DoLibInit();		// Init the Burn library's driver
	if (status) {
		if (status & 2) {
			BurnDrvExit();			// Exit the driver

			scrnTitle();
			FBAPopupAddText(PUF_TEXT_DEFAULT, MAKEINTRESOURCE(IDS_ERR_BURN_INIT), BurnDrvGetTextA(DRV_FULLNAME));
			FBAPopupDisplay(PUF_TYPE_WARNING);
		}

		mediaReInit();
		return 1;
	}

	// ==> for changing sound track
	parseTracklist();
	// <==

	romLoader.switchInterface();

	driverOkay = 1;					// Okay to use all BurnDrv functions

	// enable controls
	preferenceEnable();

	bSaveRAM = false;
	if (kNetGame) {
		kailleraInitInput();
//		kailleraGetInput();			// no real point of putting it here.. its not gonna get player one dip switches
	} else {
		if (restore) {
			statedAuto(0);
			bSaveRAM = true;

			configCheatLoad();
		}
	}

	// Reset the speed throttling code, so we don't 'jump' after the load
	runReset();

	mediaReInit();

	menuSync(MENUT_ALL);
	scrnTitle();

	return 0;
}

int drvInitCallback()
{
	return BurnerDrvInit(BurnGetDrvSelect(), false);
}

int BurnerDrvExit()
{
	// close modeless dialogs
	dialogManager.clear();
	jukeDestroy();

	if (driverOkay) {
		stopReplay();
		aviStop();

		videoInterface.exit();

		InvalidateRect(hScrnWnd, NULL, 1);
		UpdateWindow(hScrnWnd);		// Blank screen window

		if (BurnGetDrvSelect() < BurnGetDrvCount()) {
			memCardEject();			// Eject memory card if present

			if (bSaveRAM) {
				statedAuto(1);		// Save NV (or full) RAM
				bSaveRAM = false;
			}

			configGameSave(true);	// save game config

			gameInpExit();			// Exit game input
			BurnDrvExit();			// Exit the driver
		}
	}

	driverOkay = 0;					// Stop using the BurnDrv functions

	// enable controls
	preferenceEnable();

	runPause = 0;					// Don't pause when exitted

	if (audOkay) {
		// Write silence into the sound buffer on exit, and for drivers which don't use pBurnSoundOut
		audWriteSlience();
	}

	BurnSetDrvSelect(~0U);			// no driver selected
	nBurnLayer = 0xFF;				// show all layers

	scrnTitle();

	return 0;
}
